package com.zhiyou.app.common.util;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaMediaAsyncCheckResult;
import cn.binarywang.wx.miniapp.bean.security.WxMaMediaSecCheckCheckRequest;
import cn.binarywang.wx.miniapp.bean.security.WxMaMsgSecCheckCheckRequest;
import cn.binarywang.wx.miniapp.bean.security.WxMaMsgSecCheckCheckResponse;
import cn.hutool.core.map.MapUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.zhiyou.app.common.constant.UserHandler;
import com.zhiyou.app.common.exception.BizException;
import com.zhiyou.app.pojo.bo.LoginUser;
import com.zhiyou.app.pojo.bo.SecCheckResult;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.*;


@Component
public class SecCheckUtil {
    private static final WxMaService wxMaService = SpringUtil.getBean(WxMaService.class);
    private static final Map<String, CompletableFuture<SecCheckResult>> WAIT_FOR_SEC_CHECK_MAPPING = new ConcurrentHashMap<>();
    private static final Map<String, String> SEC_CHECK_RESULT_MAPPING = MapUtil
            .builder("100", "正常")
            .put("10001", "广告")
            .put("20001", "政治")
            .put("20002", "色情")
            .put("20003", "辱骂")
            .put("20006", "违法犯罪")
            .put("20008", "欺诈")
            .put("20012", "低俗")
            .put("20013", "版权")
            .put("21000", "其他")
            .build();

    public static void notifySecCheckResult(String key, SecCheckResult secCheckResult) {
        CompletableFuture<SecCheckResult> future = WAIT_FOR_SEC_CHECK_MAPPING.get(key);
        if (future != null && !future.isDone()) {
            // 完成future，返回
            future.complete(secCheckResult);
            // 移除已处理的订单
            WAIT_FOR_SEC_CHECK_MAPPING.remove(key);
        }
    }

    public static String getLabel(String label) {
        return SEC_CHECK_RESULT_MAPPING.getOrDefault(label, "通过");
    }

    public String secCheckImg(String url) {
        LoginUser loginUser = UserHandler.getLoginUser();
        if (UserHandler.getLoginUser() == null) {
            throw new BizException("请先登录");
        }
        WxMaMediaSecCheckCheckRequest requestParam = WxMaMediaSecCheckCheckRequest.builder()
                .mediaType(2)
                .mediaUrl(url)
                .openid(loginUser.getUserEntity().getOpenId()).scene(1).version(2).build();
        try {
            WxMaMediaAsyncCheckResult wxMaMediaAsyncCheckResult = wxMaService.getSecurityService().mediaCheckAsync(requestParam);
            return wxMaMediaAsyncCheckResult.getTraceId();
        } catch (WxErrorException e) {
            throw new BizException("文件安全校验失败", e.getError().getErrorMsg());
        }
    }

    public String secCheckAudio(String url) {
        LoginUser loginUser = UserHandler.getLoginUser();
        if (UserHandler.getLoginUser() == null) {
            throw new BizException("请先登录");
        }
        WxMaMediaSecCheckCheckRequest requestParam = WxMaMediaSecCheckCheckRequest.builder()
                .mediaType(1)
                .mediaUrl(url)
                .openid(loginUser.getUserEntity().getOpenId()).scene(1).version(2).build();
        try {
            WxMaMediaAsyncCheckResult wxMaMediaAsyncCheckResult = wxMaService.getSecurityService().mediaCheckAsync(requestParam);
            return wxMaMediaAsyncCheckResult.getTraceId();
        } catch (WxErrorException e) {
            throw new BizException("文件安全校验失败", e.getError().getErrorMsg());
        }
    }

    public String secCheckTextContent(String content) {
        LoginUser loginUser = UserHandler.getLoginUser();
        if (UserHandler.getLoginUser() == null) {
            throw new BizException("请先登录");
        }
        WxMaMsgSecCheckCheckRequest requestParam = WxMaMsgSecCheckCheckRequest.builder()
                .content(content)
                .openid(loginUser.getUserEntity().getOpenId()).scene(1).version("2").build();
        try {
            WxMaMsgSecCheckCheckResponse wxMaMsgSecCheckCheckResponse = wxMaService.getSecurityService().checkMessage(requestParam);
            return wxMaMsgSecCheckCheckResponse.getTraceId();
        } catch (WxErrorException e) {
            throw new BizException("文本安全校验失败", e.getError().getErrorMsg());
        }
    }

    public CompletableFuture<SecCheckResult> waitForSecCheckResult(int timeoutSeconds, String url, String content) {
        String traceId = null;
        if (content == null && url != null) {
            boolean isImage = UrlFileTypeChecker.isImageByUrlPath(url);
            boolean isAudio = UrlFileTypeChecker.isAudioByUrlPath(url);
            if (isImage) {
                traceId = secCheckImg(url);
            } else if (isAudio) {
                traceId = secCheckAudio(url);
            }
        } else {
            traceId = secCheckTextContent(content);
        }
        CompletableFuture<SecCheckResult> future = new CompletableFuture<>();
        WAIT_FOR_SEC_CHECK_MAPPING.put(traceId, future);
        // 设置超时任务
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
        scheduler.schedule(() -> {
            // 超时后如果还未完成，则返回等待状态
            if (!future.isDone()) {
                throw new BizException("文本/文件安全检测超时");
            }
            scheduler.shutdown();
        }, timeoutSeconds, TimeUnit.SECONDS);
        return future;
    }
}
